/**
  ******************************************************************************
  * @file           : modbus.h
  * @brief          : Header for modbus.c file.
  *                   This file contains the common defines of the application.
  ******************************************************************************
  * @attention
  *
  ******************************************************************************
  */

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __MODBUS_H
#define __MODBUS_H

#include <stdint.h>
#include "gv.h"

#define MODBUS_LOCAL_STATION_ADDRESS  0x01u

#define MODBUS_RECEIVE_MAXLEN         256u
#define MODBUS_FRAME_MINLEN           8u      /* 最小帧长 事务标识符2+协议标识符2+报文长度2+从站地址1+功能码1 */
#define MODBUS_01RD_COILS_QUAMAX      0x07D0u /*  */
#define MODBUS_02RD_DISINPUTS_QUAMAX  0x07D0u /*  */
#define MODBUS_03RD_HOLDREG_QUAMAX    0x007Du /*  */
#define MODBUS_04RD_INPUTREG_QUAMAX   0x007Du /*  */
#define MODBUS_15WT_MULTICOIL_QUAMAX  0x07B0u /*  */
#define MODBUS_16WT_MULTIREG_QUAMAX   0x007Bu /*  */

#define BIGENDIAN_TO_U16(x, y)        (((((uint16_t)x)<<8) & 0xff00u) + y)
//#define BIGENDIAN_U16_TO_U8X2(u, y, z)     (((((uint16_t)x)<<8) & 0xff00u) + y)

typedef enum
{
  MODBUS_FUNCODE_01RD_COILS     = 0X01u,  /* 读线圈 */
  MODBUS_FUNCODE_02RD_DISINPUTS = 0X02u,  /* 读离散输入 */
  MODBUS_FUNCODE_03RD_HOLDREG   = 0X03u,  /* 读保持寄存器 */
  MODBUS_FUNCODE_04RD_INPUTREG  = 0X04u,  /* 读输入寄存器 */
  MODBUS_FUNCODE_05WT_SINGLCOIL = 0X05u,  /* 写单个线圈 */
  MODBUS_FUNCODE_06WT_SINGLREG  = 0X06u,  /* 写单个寄存器 */
  MODBUS_FUNCODE_15WT_MULTICOIL = 0X0Fu,  /* 写多个线圈 */
  MODBUS_FUNCODE_16WT_MULTIREG  = 0X10u,  /* 写多个寄存器 */
}Modbus_FunCodeEnum;

typedef struct
{
  const uint16_t cosize;
  const uint16_t disize;
  const uint16_t irsize;
  const uint16_t hrsize;
  uint8_t  * coils;         /* 线圈 */
  uint8_t  * disinput;      /* 离散输入 */
  uint16_t * inputreg;      /* 输入寄存器 */
  uint16_t * holdreg;       /* 保持寄存器 */
}Modbus_MemoryMapStru;

typedef struct _Modbus_MapDisinputStru
{
  uint8_t empty;
  uint8_t di1;
  uint8_t di2;
  uint8_t di3;
  uint8_t di4;
  uint8_t di5;
  uint8_t di6;
  uint8_t di7;
  uint8_t di8;
  uint8_t di9;
  uint8_t di10;
  uint8_t di11;
  uint8_t di12;
  uint8_t di13;
  uint8_t di14;
  uint8_t di15;
  uint8_t di16;
}Modbus_MapDisinputStru;

/* 因为从两份文档中得到的地址不一致 若地址有误 删除整千地址试试 */
typedef struct _Modbus_MapHoldregStru
{
  uint16_t empty0;                /* 0 */
  uint16_t empty1[1000-0-1];      /* 1~999 */
  uint16_t empty2;                /* 1000 */
  uint16_t adj_year;              /* 1001 */
  uint16_t adj_month;             /* 1002 */
  uint16_t adj_day;               /* 1003 */
  uint16_t adj_hour;              /* 1004 */
  uint16_t adj_minute;            /* 1005 */
  uint16_t adj_second;            /* 1006 */
  uint16_t adj_cmd;               /* 1007 */
  uint16_t empty3[2000-1007-1];   /* 1007~1999 */
  uint16_t empty4;                /* 2000 */
  uint32_t weight_factor_base;    /* 2001 2002 */
  int32_t  zero_code_ave;         /* 2003 2004 */
  int32_t  zero_code_uplimit;     /* 2005 2006 */
  uint16_t len_circle_mode;       /* 2007 */
  uint32_t manu_zero_range;       /* 2008 2009 */
  uint16_t auto_zero_onoff;       /* 2010 */
  uint32_t auto_zero_range;       /* 2011 2012 */
  float    fxszn_empty;           /* 2013 2014 流量显示阻尼 */
  float    flowrate_lowlim_tph;   /* 2015 2016 */
  uint16_t xllxskg_empty;         /* 2017 小流量显示kg */
  uint16_t wad_preset_enable;     /* 2018 */
  int32_t  wad_preset_value;      /* 2019 2020 */
  uint16_t sad_preset_enable;     /* 2021 */
  uint32_t sad_preset_value;      /* 2022 2023 */
  uint16_t pdjsbz_empty;          /* 2024 监视皮带标志 */
  float    belt_period_s;         /* 2025 2026 */
  float    belt_length_m;         /* 2027 2028 */
  float    effect_length_mm;      /* 2029 2030 */
  uint16_t speed_wheel_pls;       /* 2031 */
  float    speed_wheel_cir_mm;    /* 2032 2033 */
  float    measuring_range_tph;   /* 2034 2035 */
  uint16_t cal_shiwu_wtacc;       /* 2036 */
  uint16_t east_longitude_du;     /* 2037 */
  uint16_t east_longitude_fen;    /* 2038 */
  float    east_longitude_miao;   /* 2039 2040 */
  uint16_t north_latitude_du;     /* 2041 */
  uint16_t north_latitude_fen;    /* 2042 */
  float    north_latitude_miao;   /* 2043 2044 */
  float    prod_year_capacity_t;  /* 2045 2046 */          /* 核定年生产能力 */
  float    prod_month_capacity_t; /* 2047 2048 */          /* 核定月生产能力 */
  float    prod_day_capacity_t;   /* 2049 2050 */          /* 核定日生产能力 */
  float    prod_hour_capacity_t;  /* 2051 2052 */          /* 核定时生产能力 */
  uint16_t mymzsxs_empty;         /* 2053 毛原煤折算系数 */
  float    smycz_empty;           /* 2054 2055 输煤异常值 */
  uint16_t empty5[2500-2055-1];   /* 2056~2499  当前地址-上面地址+1*/
  uint16_t empty6;                /* 2500 */
  uint16_t sjzhscsj_empty;        /* 2501 数据最后上传时间 */
  uint16_t empty7[2];             /* 2502 2503 */
}Modbus_MapHoldregStru;

typedef struct _Modbus_MapIntputRegStru
{
  uint16_t empty0;                /* 0000 */
  uint16_t empty1[1000-0-1];      /* 0~999 */
  uint16_t empty2;                /* 1000 */
  uint16_t rtc_year;              /* 1001 */
  uint16_t rtc_month;             /* 1002 */
  uint16_t rtc_day;               /* 1003 */
  uint16_t rtc_hour;              /* 1004 */
  uint16_t rtc_minute;            /* 1005 */
  uint16_t rtc_second;            /* 1006 */
  uint16_t empty3[2000-1006-1];   /* 1007~1999 */
  uint16_t empty4;                /* 2000 */
  uint32_t weight_factor_base;    /* 2001 2002 */
  int32_t  zero_code_ave;         /* 2003 2004 */
  int32_t  zero_code_uplimit;     /* 2005 2006 */
  uint16_t len_circle_mode;       /* 2007 */
  uint32_t manu_zero_range;       /* 2008 2009 */
  uint16_t auto_zero_onoff;       /* 2010 */
  uint32_t auto_zero_range;       /* 2011 2012 */
  float    fxszn_empty;           /* 2013 2014 流量显示阻尼 */
  float    flowrate_lowlim_tph;   /* 2015 2016 */
  uint16_t xllxskg_empty;         /* 2017 小流量显示kg */
  uint16_t wad_preset_enable;     /* 2018 */
  int32_t  wad_preset_value;      /* 2019 2020 */
  uint16_t sad_preset_enable;     /* 2021 */
  uint32_t sad_preset_value;      /* 2022 2023 */
  uint16_t pdjsbz_empty;          /* 2024 监视皮带标志 */
  float    belt_period_s;         /* 2025 2026 */
  float    belt_length_m;         /* 2027 2028 */
  float    effect_length_mm;      /* 2029 2030 */
  uint16_t speed_wheel_pls;       /* 2031 */
  float    speed_wheel_cir_mm;    /* 2032 2033 */
  float    measuring_range_tph;   /* 2034 2035 */
  uint16_t cal_shiwu_wtacc;       /* 2036 */
  uint16_t east_longitude_du;     /* 2037 */
  uint16_t east_longitude_fen;    /* 2038 */
  float    east_longitude_miao;   /* 2039 2040 */
  uint16_t north_latitude_du;     /* 2041 */
  uint16_t north_latitude_fen;    /* 2042 */
  float    north_latitude_miao;   /* 2043 2044 */
  float    prod_year_capacity_t;  /* 2045 2046 */          /* 核定年生产能力 */
  float    prod_month_capacity_t; /* 2047 2048 */          /* 核定月生产能力 */
  float    prod_day_capacity_t;   /* 2049 2050 */          /* 核定日生产能力 */
  float    prod_hour_capacity_t;  /* 2051 2052 */          /* 核定时生产能力 */
  uint16_t mymzsxs_empty;         /* 2053 毛原煤折算系数 */
  float    smycz_empty;           /* 2054 2055 输煤异常值 */
  uint16_t yscsjsjd_year_empty;   /* 2056 C已上传数据时间点年 */
  uint16_t yscsjsjd_month_empty;  /* 2057 C已上传数据时间点月 */
  uint16_t yscsjsjd_day_empty;    /* 2058 C已上传数据时间点日 */
  uint16_t yscsjsjd_hour_empty;   /* 2059 C已上传数据时间点时 */
  uint16_t yscsjsjd_minute_empty; /* 2060 C已上传数据时间点分 */
  uint16_t yscsjsjd_second_empty; /* 2061 C已上传数据时间点秒 */
  uint16_t empty5[3000-2061-1];   /* 2062~2999 */
  uint16_t empty6;                /* 3000 */
  uint32_t count_bb_num_empty;    /* 3001 3002 count版本_数值 */
  int32_t  weight_code_ave;       /* 3003 3004 M重量内码 */
  uint32_t speed_code_ave;        /* 3005 3006 M速度内码 */
  float    flowrate_tph;          /* 3007 3008 MR流量_吨每小时 */
  float    flowrate_zn_tph;       /* 3009 3010 MR流量_阻尼后_吨每小时 */
  float    belt_speed_mms;        /* 3011 3012 MR皮带速度_毫米每秒 */
  uint16_t empty7;                /* 3013 S分站通讯延时处理后状态 */
  uint16_t empty8;                /* 3014 S分站盖 */
  uint16_t empty9;                /* 3015 S分站电源盖 */
  uint16_t empty10;               /* 3016 SUPS通讯状态 */
  uint16_t empty11;               /* 3017 SUPS电池状态 */
  uint16_t empty12;               /* 3018 S市电状态 */
  uint16_t empty13;               /* 3019 S终端柜门 */
  uint16_t empty14;               /* 3020 S输煤设备开停状态 */
  uint16_t empty15;               /* 3021 S输煤状态 */
  uint16_t empty16;               /* 3022 S网络状态 */
  uint16_t ics_num[8];            /* 3023~3030 */
  uint16_t wt_sensor_01_num[8];   /* 3031~3038 */
  uint16_t wt_sensor_02_num[8];   /* 3039~3046 */
  uint16_t wt_sensor_03_num[8];   /* 3047~3054 */
  uint16_t wt_sensor_04_num[8];   /* 3055~3062 */
  uint16_t speed_sensor_num[8];   /* 3063~3070 */
  uint16_t wt_sensor_01_state;    /* 3071 */
  uint16_t wt_sensor_02_state;    /* 3072 */
  uint16_t wt_sensor_03_state;    /* 3073 */
  uint16_t wt_sensor_04_state;    /* 3074 */
  uint16_t speed_sensor_state;    /* 3075 */
  uint32_t wt_sensor_01_code;     /* 3076 3077 */
  uint32_t wt_sensor_02_code;     /* 3078 3079 */
  uint32_t wt_sensor_03_code;     /* 3080 3081 */
  uint32_t wt_sensor_04_code;     /* 3082 3083 */
  uint32_t speed_sensor_code;     /* 3084 3085 */
  uint16_t empty17[4000-3085-1];  /* 3086 3999 */
  uint16_t empty18;               /* 4000 */
  float    total_acc_t;           /* 4001 4002 MR总产量_t */
  float    year_acc_t;            /* 4003 4004 MR年产量_t */
  float    month_acc_t;           /* 4005 4006 MR月产量_t */
  float    day_acc_t;             /* 4007 4008 MR日产量_t */
  float    hour_acc_t;            /* 4009 4010 MR时产量_t */
  float    class_acc_t;           /* 4011 4012 MR班产量_t */
}Modbus_MapIntputRegStru;

typedef struct _Modbus_MapCoilsRegStru
{
  uint8_t emtyp[32];
}Modbus_MapCoilsRegStru;

typedef struct
{
  Modbus_MapCoilsRegStru  co;
  Modbus_MapDisinputStru  di;
  Modbus_MapIntputRegStru ir;
  Modbus_MapHoldregStru   hr;
}Modbus_MemMapStru;

extern uint8_t modbus_tcp_process(const uint8_t *in, uint16_t inlen, uint8_t *out, uint16_t *outlen);
extern void modbus_init(void);

extern void mb_coils_donwload(uint16_t startaddr, uint16_t quantity, GlobalVariablesStru *pgv);
extern void mb_holdreg_donwload(uint16_t startaddr, uint16_t quantity, GlobalVariablesStru *pgv);

extern void mb_inputreg_rd_update(Modbus_MapIntputRegStru *ir);
extern void mb_holdreg_rd_update(Modbus_MapHoldregStru *hr);

#endif /* __MODBUS_H */
